%==========================================================================
%=  This file is part of the Sound Restoration Project
%=  (c) Copyright Industrial Mathematics Institute
%=                University of South Carolina, Department of Mathematics
%=  ALL RIGHTS RESERVED
%=
%=  Author: Borislav Karaivanov
%==========================================================================

%==========================================================================
% List of the files on which this procedure depends:
%
% createMissingDirs.m 
% generateOutputDirectory.m 
% getBitDepthFromVideoObject.m
% getFileSequenceFromRepresentative.m 
% patientlyKeepTryingToReadUntilErrorFree.m 
% readAndCheckVideoFrames.m 
% readVideoFrames.m
% setUpProjectDirectories.m 
% Image processing toolbox
%
%==========================================================================

%==========================================================================
% The function "setUpProjectWithMatlabReadableMovie" takes a string
% specifying a Matlab-readable movie and a Matlab video object associated
% with that movie and sets up a project structure with various information
% relevant to optical sound extraction.
% INPUT: "projectStruct" is a structure whose fields store various
% information relevant to optical sound extraction.
% OUTPUT: "projectStruct" returns a structure whose fields store various
% information relevant to optical sound extraction from the given type of
% files.
%==========================================================================
function projectStruct = setUpProjectWithMatlabReadableMovie(projectStruct)

% Try to get multi-media information from the given file for the sake of
% checking if it is Matlab-readable.
mmfileinfo(projectStruct.inFile.name);

% Try to create a video object.
videoObj = VideoReader(projectStruct.inFile.name);

% Test by reading several video frame at random.
indArr = [1; randi(videoObj.NumberOfFrames, 5, 1); videoObj.NumberOfFrames];
for k = 1:numel(indArr)
    imageArr = read(videoObj, k);
%     image(imageArr);
end

%==========================================================================
% If this line is reached, we assume that the given file is a movie in a
% Matlab-readable format.
%==========================================================================
% Classify the input file as a Matlab-readable video.
projectStruct.inFile.kind = 'videoMatlab';

% Store the video object.
projectStruct.videoObj = videoObj;
% Set the total number of frames in the video.
%projectStruct.numFrames = videoObj.NumberOfFrames;
% Set the array of frame indices.
projectStruct.inFile.frameRangeArr = [1, videoObj.NumberOfFrames];
projectStruct.workFile.frameRangeArr = [1, videoObj.NumberOfFrames];
% Set the dimensions of each frame.
projectStruct.height = videoObj.Height;
projectStruct.width = videoObj.Width;
% Set the bit depth per channel. For instance, Matlab reports three 8-bit
% channels as 24 bits per pixel.
projectStruct.workFile.bitDepth = getBitDepthFromVideoObject(videoObj);
% Set the total time of the video in seconds.
projectStruct.duration = videoObj.Duration;
% Set the frame rate of the video in case it is constant. The case of
% variable frame rate is not covered at present but could be.
projectStruct.frameRate = videoObj.FrameRate;
% Set a string describing the video formatting.
%projectStruct.videoFormat = videoObj.VideoFormat;
% Set the directory path, name without path and extension, and extension of
% the input movie.
[projectStruct.inFile.dirPath, projectStruct.inFile.namePrefixNoPath, ...
    projectStruct.inFile.fileExt] = fileparts(projectStruct.inFile.name);
projectStruct.inFile.dirPath = [projectStruct.inFile.dirPath filesep];
projectStruct.inFile.fileExt = projectStruct.inFile.fileExt(2:end);

% Set and create the output and scratch directories. Also set a project
% file name and file name prefix for converted image files if any are to be
% generated later on.
projectStruct = setUpProjectDirectories(projectStruct);

% % Set a handle to a reading function.
% projectStruct.readFramesFunctHandle = @(indRange, doConvertToGray) ...
%     readVideoFrames(projectStruct.videoObj, [indRange(1), indRange(end)], doConvertToGray);

% Set a handle to a safer reading function.
projectStruct.readFramesFunctHandle = @(indRange, doConvertToGray) ...
    readAndCheckVideoFrames(projectStruct.videoObj, [indRange(1), indRange(end)], doConvertToGray);

% Set a handle to a safer reading function.
projectStruct.readFramesSafelyFunctHandle = @(indRange, doConvertToGray) ...
    readAndCheckVideoFrames(projectStruct.videoObj, [indRange(1), indRange(end)], doConvertToGray);

return;
% end of the function "setUpProjectWithMatlabReadableMovie"
